﻿using System.Globalization;

namespace HelenServer.Core;

public static partial class Helen
{
    public const string Delimiter = "#";

    public static DateTime MinimumDate { get; } = new(1753, 1, 1, 12, 0, 0);

    public static IServiceProvider Services { get; set; } = null!;

    public static IDictionary<string, string> Metadata { get; set; } = new Dictionary<string, string>();

    public static string NewGuid => Guid.NewGuid().ToString("N");

    public static bool TryFromBase64String(string base64, out string json)
    {
        var buffer = new Span<byte>(new byte[base64.Length]);

        var width = (base64.Length / 4 * 4) + (base64.Length % 4 == 0 ? 0 : 4);

        base64 = base64.PadRight(width, '=');

        if (Convert.TryFromBase64String(base64, buffer, out _))
        {
            json = Encoding.UTF8.GetString(Convert.FromBase64String(base64));

            return true;
        }
        else
        {
            json = string.Empty;

            return false;
        }
    }

    public static string Base64EncodeImage(Stream stream, string extension)
    {
        using var ms = new MemoryStream();

        var __buffer = new byte[1024];
        var r = -1;
        while ((r = stream.Read(__buffer, 0, __buffer.Length)) > 0)
        {
            ms.Write(__buffer, 0, r);
        }

        return $"data:image/{extension};base64,{Convert.ToBase64String(ms.GetBuffer())}";
    }

    public static T ToEnum<T>(this string enumName)
    {
        return (T)Enum.Parse(typeof(T), CultureInfo.CurrentCulture.TextInfo.ToTitleCase(enumName));
    }

    public static string GetEnumValue<T>(int value)
    {
        return Enum.GetName(typeof(T), value) ?? string.Empty;
    }

    public static string GetEnumDisplayValue<T>(T @enum)
    {
        var type = typeof(T);

        var field = type.GetField(Enum.GetName(typeof(T), @enum!)!)!;

        var ev = field.GetCustomAttribute<DisplayValueAttribute>();

        return ev is null ? string.Empty : ev.Value;
    }

    public static string GenerateVerifyCode(int length)
    {
        var result = new StringBuilder();

        for (var i = 0; i < length; i++)
        {
            var r = new Random(Guid.NewGuid().GetHashCode());
            result.Append(r.Next(0, 10));
        }

        return result.ToString();
    }

    public static string[] ResolveCompositField(string value)
    {
        return value.Split(Delimiter);
    }

    public static string CompositField(string[] values)
    {
        return string.Join(Delimiter, values);
    }

    public static int ComputeCount<T>(this IEnumerable<T[]> source)
    {
        var count = 0;
        foreach (var item in source)
        {
            count += item.Length;
        }

        return count;
    }
}